package com.cfw.authority;

import java.io.IOException;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.xpath.XPathExpressionException;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cfw.properties.CustomProperties;
import com.cfw.util.HttpUtil;

/**
 * URL접근 보안을 위한 서블릿 필터
 * <br/><b>History</b><br/>
 * <pre>
 * 2012. 2. 10. 최초작성
 * </pre>
 * @author 박형일
 * @version 1.0
 */
public class AuthorityFilter implements Filter {

	private final static Logger logger = LoggerFactory.getLogger(AuthorityFilter.class);
	
	public void destroy() { 
		// 구현사항 없슴
	}

	/* url을 이용 호출 모듈명을 알아내고, AuthorityManager를 이용하여 현재 접속자가 모듈명에 대하여 
	 * 갖는 권한을 산출하며, 접근허용여부를 판단한다. 
	 * (non-Javadoc)
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	public void doFilter(final ServletRequest arg0, final ServletResponse arg1,
			final FilterChain arg2) throws IOException, ServletException {
		
		final HttpServletRequest request = (HttpServletRequest)arg0;
		final HttpServletResponse response = (HttpServletResponse)arg1; 
		final String sid = AuthorityUtil.getSid(request);

		String jtp = request.getParameter("_jtp");
		final String par = request.getParameter("_par");
		String[] roleGroupName = null;
		String[] userGroupName = null;
		
		if (StringUtils.isEmpty(jtp)) { jtp = "R"; }
		
		try {
			final SessionInfo sessionInfo =	SessionInfoSupport.getSessionAttribute(request.getSession());

			if (sessionInfo != null) {
				roleGroupName =	sessionInfo.getRoleGroupName();
				userGroupName =	sessionInfo.getUserGroupName();
			}
			
			Set<String> set = AuthorityManager.getInstance().getAuth(sid, roleGroupName, userGroupName, par, sessionInfo != null, null, HttpUtil.getClientIP(request));
			logger.debug("result set:" + set);
			
			if (set == null || !set.contains(jtp)) {
				// 권한이  허용되지 않았으므로 다른 페이지로 이동
				String pageId =	"";
				
				if (sessionInfo == null) {
					// 권한이 필요한 페이지로 이동하려 하였으나, 세션변수가 없을 경우
					pageId = "url.exception.nosession";
				} else {
					// 세션변수는 있지만 권한이 없을 경우
					pageId = "url.exception.auth";
				}
				
	            final RequestDispatcher dispatcher = request.getSession().getServletContext().getRequestDispatcher(CustomProperties.getProperty(pageId));
	            dispatcher.forward(request, response);
			} else {
				request.setAttribute("authority", set);
			}
		} catch (XPathExpressionException e) {
			logger.error(e.getMessage());
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		
		arg2.doFilter(request, response);
	}

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	public void init(final FilterConfig arg0) throws ServletException {
		//
	}

}
